/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-04-20
*/
package com.rzico.core.service;

import com.rzico.base.BaseMapper;
import com.rzico.base.impl.BaseServiceImpl;
import com.rzico.core.entity.SysMch;
import com.rzico.core.entity.SysReport;
import com.rzico.core.entity.SysUser;
import com.rzico.exception.CustomException;
import com.rzico.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.export.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import com.rzico.core.mapper.SysReportMapper;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <pre>
 * 统计报表业务类
 * </pre>
 *
 * @author Rzico Boot
 * @version 1.0
 */
@Service
@Slf4j
public class SysReportService extends BaseServiceImpl<SysReport, String> {

    @Autowired
    private SysReportMapper sysReportMapper;

    @Resource
    private DataSource dataSource;

    @Override
    public BaseMapper<SysReport, String> getMapper() {
        return sysReportMapper;
    }


    /**
     * 打印模板到PDF
     * @param fileName
     * @param parameters
     * @param detailList
     * @param response
     * @throws SQLException
     * @throws ClassNotFoundException
     * @throws JRException
     * @throws IOException
     */
    public void ReportToPdf(
            String fileName, Map<String, Object> parameters, List detailList,
            HttpServletResponse response) throws SQLException, ClassNotFoundException, JRException, IOException {
        parameters = parameters == null ? new HashMap<>() : parameters;
        //获取文件流
        ClassPathResource resource = new ClassPathResource("jaspers" + File.separator + fileName+".jasper");
        InputStream jasperStream = resource.getInputStream();
        log.info("加载的文件名：[{}]", resource.getFilename());
        final OutputStream outputStream = response.getOutputStream();
        try {

            JasperReport jasperReport = (JasperReport) JRLoader.loadObject(jasperStream);
            JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(detailList);
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "inline;");
            JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream);
            log.info("ReportToPdf  success");
        } catch (Exception e){
            e.getMessage();
            log.info("message: [{}]", e.getMessage());
            throw new CustomException("打印模板到PDF");
        } finally {
            outputStream.flush();
            outputStream.close();
            jasperStream.close();
        }


    }

    /**
     * 打印模板到PDF
     * @param fileName
     * @param parameters
     * @param response
     * @throws SQLException
     * @throws ClassNotFoundException
     * @throws JRException
     * @throws IOException
     */
    public void ReportToPdfBySql(String fileName, Map<String, Object> parameters, String sql, HttpServletResponse response) throws SQLException, ClassNotFoundException, JRException, IOException {
        parameters = parameters == null ? new HashMap<>() : parameters;
        //获取文件流
        ClassPathResource resource = new ClassPathResource("jaspers" + File.separator + fileName+".jasper");
        log.info("加载的文件名：[{}]", resource.getFilename());
        InputStream jasperStream = resource.getInputStream();
        final OutputStream outputStream = response.getOutputStream();
        Connection connection = dataSource.getConnection();
        try {
            JasperReport jasperReport = (JasperReport) JRLoader.loadObject(jasperStream);
            parameters.put("SQL", sql);
            log.info("SQL：[{}]", sql);
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, connection);
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "inline;");
            response.setHeader("Access-Control-Allow-Methods","OPTIONS,POST,GET");
            response.setHeader("Access-Control-Allow-Headers","x-requested-with,content-type");
            response.setHeader("Access-Control-Allow-Origin","*");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream);
            log.info("ReportToPdfBySql  success");
        } catch (Exception e){
            log.info("message: [{}]", e.getMessage());
            throw new CustomException("印模板到PDF异常");
        } finally {
            outputStream.flush();
            outputStream.close();
            jasperStream.close();
            //必须关闭
            if (!connection.isClosed()){
                connection.close();
            }
        }


    }

    /**
     * 打印模板到Excel
     * @param fileName
     * @param parameters
     * @param response
     * @throws SQLException
     * @throws ClassNotFoundException
     * @throws JRException
     * @throws IOException
     */
    public void ReportToExcelBySql(String fileName, Map<String, Object> parameters, String sql,
                                   HttpServletResponse response) throws SQLException, ClassNotFoundException, JRException, IOException {
        parameters = parameters == null ? new HashMap<>() : parameters;

        //获取文件流
        ClassPathResource resource = new ClassPathResource("jaspers" + File.separator + fileName+".jasper");
        log.info("加载的文件名：[{}]", resource.getFilename());
        InputStream jasperStream = resource.getInputStream();
        final OutputStream outputStream = response.getOutputStream();
        Connection connection = dataSource.getConnection();
        try {
            JasperReport jasperReport = (JasperReport) JRLoader.loadObject(jasperStream);
            parameters.put("SQL", sql);
            log.info("SQL：[{}]", sql);
            String reportName = String.valueOf(parameters.get("REPORT_NAME"));
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, connection);
            String generateFileName = reportName+".xlsx";
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-disposition", "attachment; filename="  + URLEncoder.encode(generateFileName, "utf8"));

            //设置导出时参数
            SimpleXlsxReportConfiguration conf = new SimpleXlsxReportConfiguration();
            conf.setWhitePageBackground(false);
            conf.setDetectCellType(true);

            JRXlsxExporter exporter = new JRXlsxExporter();
            exporter.setConfiguration(conf);
            //设置输入项
            ExporterInput exporterInput = new SimpleExporterInput(jasperPrint);
            exporter.setExporterInput(exporterInput);

            //设置输出项
            OutputStreamExporterOutput exporterOutput = new SimpleOutputStreamExporterOutput(response.getOutputStream());
            exporter.setExporterOutput(exporterOutput);

            exporter.exportReport();

            log.info("ReportToExcelBySql  success");
        } catch (Exception e){
            log.info("message: [{}]", e.getMessage());
            throw new CustomException("印模板到Excel异常");
        } finally {
            outputStream.flush();
            outputStream.close();
            jasperStream.close();
            //必须关闭
            if (!connection.isClosed()){
                connection.close();
            }
        }


    }
    /**
     * 打印模板到Excel
     * @param fileName
     * @param parameters
     * @param detailList
     * @param response
     * @throws Exception
     */
    public void ReportToExcel(
            String fileName,Map<String, Object> parameters,List detailList, HttpServletResponse response) throws Exception {
        //String urlResource = this.getClass().getClassLoader().getResource("template/CustBatchConfirmExcel.jasper").getPath();
        //InputStream inpst = this.getClass().getResourceAsStream("/template/CustBatchConfirmExcel.jasper");
        //用上面那种方式，打成jar包后 无法定位到文件即读不到文件，用下面的读取流才可以
        ClassPathResource resource = new ClassPathResource("jaspers" + File.separator + fileName+".jasper");
        InputStream inpst = resource.getInputStream();
        log.info("加载的文件名：[{}]", resource.getFilename());
        //batchCompleteVos是List类型数据源
        JRDataSource dataSource = new JRBeanCollectionDataSource(detailList, true);
        //print文件
        //JasperPrint print = JasperFillManager.fillReport(urlResource, params, dataSource);
        JasperPrint print = JasperFillManager.fillReport(inpst, parameters, dataSource);

        //以附件形式保存文件
        String generateFileName = "制作安装完工确认单.xlsx";
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-disposition", "attachment; filename="  + URLEncoder.encode(generateFileName, "utf8"));

        //设置导出时参数
        SimpleXlsxReportConfiguration conf = new SimpleXlsxReportConfiguration();
        conf.setWhitePageBackground(false);
        conf.setDetectCellType(true);

        JRXlsxExporter exporter = new JRXlsxExporter();
        exporter.setConfiguration(conf);
        //设置输入项
        ExporterInput exporterInput = new SimpleExporterInput(print);
        exporter.setExporterInput(exporterInput);

        //设置输出项
        OutputStreamExporterOutput exporterOutput = new SimpleOutputStreamExporterOutput(response.getOutputStream());
        exporter.setExporterOutput(exporterOutput);

        exporter.exportReport();
    }


    /**
     * 报表打印统一函数
     * @param fileName
     * @param parameters
     * @param response
     * @throws SQLException
     * @throws ClassNotFoundException
     * @throws JRException
     * @throws IOException
     */
    public void commReportToPdf(String filePath, String fileName, Map<String, Object> parameters, String sql, HttpServletResponse response) throws SQLException, ClassNotFoundException, JRException, IOException {
        parameters = parameters == null ? new HashMap<>() : parameters;
        //获取文件流
        InputStream jasperStream = new FileInputStream(filePath + File.separator + fileName);
        final OutputStream outputStream = response.getOutputStream();
        Connection connection = dataSource.getConnection();
        try {
            JasperReport jasperReport = (JasperReport) JRLoader.loadObject(jasperStream);
            parameters.put("SQL", sql);
            log.info("SQL：[{}]", sql);
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, connection);
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "inline;");
            response.setHeader("Access-Control-Allow-Methods","OPTIONS,POST,GET");
            response.setHeader("Access-Control-Allow-Headers","x-requested-with,content-type");
            response.setHeader("Access-Control-Allow-Origin","*");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream);
            log.info("ReportToPdfBySql  success");
        } catch (Exception e){
            log.info("message: [{}]", e.getMessage());
            throw new CustomException("印模板到PDF异常");
        } finally {
            outputStream.flush();
            outputStream.close();
            jasperStream.close();
            //必须关闭
            if (!connection.isClosed()){
                connection.close();
            }
        }


    }



    /**
     * 打印模板到Excel
     * @param fileName
     * @param parameters
     * @param response
     * @throws SQLException
     * @throws ClassNotFoundException
     * @throws JRException
     * @throws IOException
     */
    public void commReportToExcelBySql(String filePath, String fileName, Map<String, Object> parameters, String sql,
                                   HttpServletResponse response) throws SQLException, ClassNotFoundException, JRException, IOException {
        parameters = parameters == null ? new HashMap<>() : parameters;
        //获取文件流
        InputStream jasperStream = new FileInputStream(filePath + File.separator + fileName);
        final OutputStream outputStream = response.getOutputStream();
        Connection connection = dataSource.getConnection();

        //获取文件流
  /*      ClassPathResource resource = new ClassPathResource("jaspers" + File.separator + fileName+".jasper");
        log.info("加载的文件名：[{}]", resource.getFilename());
        InputStream jasperStream = resource.getInputStream();
        final OutputStream outputStream = response.getOutputStream();
        Connection connection = dataSource.getConnection();*/
        try {
            JasperReport jasperReport = (JasperReport) JRLoader.loadObject(jasperStream);
            parameters.put("SQL", sql);
            log.info("SQL：[{}]", sql);
            String reportName = String.valueOf(parameters.get("REPORT_NAME"));
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, connection);
            String generateFileName = reportName+".xlsx";
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-disposition", "attachment; filename="  + URLEncoder.encode(generateFileName, "utf8"));

            //设置导出时参数
            SimpleXlsxReportConfiguration conf = new SimpleXlsxReportConfiguration();
            conf.setWhitePageBackground(false);
            conf.setDetectCellType(true);

            JRXlsxExporter exporter = new JRXlsxExporter();
            exporter.setConfiguration(conf);
            //设置输入项
            ExporterInput exporterInput = new SimpleExporterInput(jasperPrint);
            exporter.setExporterInput(exporterInput);

            //设置输出项
            OutputStreamExporterOutput exporterOutput = new SimpleOutputStreamExporterOutput(response.getOutputStream());
            exporter.setExporterOutput(exporterOutput);

            exporter.exportReport();

            log.info("ReportToExcelBySql  success");
        } catch (Exception e){
            log.info("message: [{}]", e.getMessage());
            throw new CustomException("印模板到Excel异常");
        } finally {
            outputStream.flush();
            outputStream.close();
            jasperStream.close();
            //必须关闭
            if (!connection.isClosed()){
                connection.close();
            }
        }


    }


    public void fileDownLoad(String url, String filePath, String fileName) throws Exception {
        log.info("进入到文件下载方法,下载文件名称为" + fileName);
        File file=new File(filePath);
        //判断文件夹是否存在
        if (!file.exists()){
            file.mkdirs();
        }
        FileOutputStream fileOut = null;
        HttpURLConnection conn = null;
        InputStream inputStream = null;
        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;
        try{
            URL httpUrl=new URL(url);
            conn=(HttpURLConnection) httpUrl.openConnection();
            //以Post方式提交表单，默认get方式
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            conn.setDoOutput(true);
            // post方式不能使用缓存
            conn.setUseCaches(false);
            conn.connect();
            //获取网络输入流
            inputStream = conn.getInputStream();
            bis = new BufferedInputStream(inputStream);
            //判断文件的保存路径后面是否以/结尾
            if (!filePath.endsWith("/")) {
                filePath += "/";
            }
            //写入到文件（注意文件保存路径的后面一定要加上文件的名称）
            fileOut = new FileOutputStream(filePath+fileName);
            bos = new BufferedOutputStream(fileOut);

            byte[] buf = new byte[4096];
            int length = bis.read(buf);
            //保存文件
            while(length != -1){
                bos.write(buf, 0, length);
                length = bis.read(buf);
            }
        } catch (Exception e){
            e.printStackTrace();
            System.out.println("抛出异常！！");
        } finally {
            bos.close();
            bis.close();
            conn.disconnect();
        }

    }

}
